package com.ygg.cps.afx.jdbc ;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.sql.DataSource;

import org.apache.log4j.Logger;

import com.ygg.cps.afx.constant.DBConst;
/**
 * 
 * Spring版本，保存dataSource
 * @author andy.lhc
 * 在Spring中注入一个dataSource
 */
public class ConnectionManagerV2
{
    
    private ConnectionManagerV2()
    {
    }
    
    /**
     * 保存数据库连接池，可以配多个连接池
     */
    private final static ConcurrentMap<String, DataSource> dataSourceMap = new ConcurrentHashMap<String, DataSource>();
    
    private static Logger log = Logger.getLogger(ConnectionManagerV2.class);
    
    /**
     * 把Connection放入当前线程中，控制事务
     */
    private static final ThreadLocal<Connection> transactionHolder = new ThreadLocal<Connection>();
    

    public void setDataSource(DataSource dataSource)
    {
    	if(dataSource ==null)
    		 throw new IllegalArgumentException("dataSource is null error") ;
    	dataSourceMap.put(DBConst.DEFAULT_CONNECTION_POOL, dataSource) ;
    }
    
    /**
     * 默认的key=DBConst.DEFAULT_CONNECTION_POOL
     * @param connectionPoolKey
     * @return
     */
    public DataSource getDataSource(String connectionPoolKey)
    {
    	DataSource ds = dataSourceMap.get(connectionPoolKey) ;
    	if(ds == null)
    		init(connectionPoolKey);
    	return ds ;
    }
    
    public static Connection getConnection(String connectionPoolKey)
        throws SQLException
    {
        Connection conn = transactionHolder.get();
        if (conn == null)
        {
            if (!dataSourceMap.containsKey(connectionPoolKey))
            {
            	init(connectionPoolKey);
            }
             DataSource dataSource = dataSourceMap.get(connectionPoolKey);
            try
            {
                conn = dataSource.getConnection();
                transactionHolder.set(conn);
            }
            catch (SQLException e)
            {
                log.error("从" + connectionPoolKey + "数据库连接池获取连接出错", e);
                throw e;
            }
        }
        return conn;
    }

	/**
     * 从当前线程中得到Connection
     * 在Dao  中用此方法
     * @param connectionPoolKey
     * @return
     * @throws SQLException
     */
    public static Connection getCurrentConnection()
        throws SQLException
    {
        Connection conn = transactionHolder.get();
        if(conn == null )  // 重新得到一个
        {
        	DataSource dataSource = dataSourceMap.get(DBConst.DEFAULT_CONNECTION_POOL);
        	if(dataSource == null)
        		 throw new IllegalArgumentException("dataSource is null error") ;
        	conn = dataSource.getConnection() ;
        	log.warn("dataSource:"+dataSource.getClass() +" new connection: "+conn.toString());
        	transactionHolder.set(conn);
        }
        return conn;
    }
    
    public static void beginTransaction(String connectionPoolKey)
    {
        if (!dataSourceMap.containsKey(connectionPoolKey))
        {
            init(connectionPoolKey);
        }
        DataSource dataSource = dataSourceMap.get(connectionPoolKey);
        try
        {
            Connection conn = dataSource.getConnection();
            conn.setAutoCommit(false);
            transactionHolder.set(conn);
        }
        catch (SQLException e)
        {
            log.error("beginTransaction:从" + connectionPoolKey + "数据库连接池获取连接出错", e);
        }
    }
    /**
     * 从当前线程中开启事务
     */
    public static void beginTransaction()
    {
        if (!dataSourceMap.containsKey(DBConst.DEFAULT_CONNECTION_POOL))
        {
            init(DBConst.DEFAULT_CONNECTION_POOL);
        }
        DataSource dataSource = dataSourceMap.get(DBConst.DEFAULT_CONNECTION_POOL);
        try
        {
            Connection conn = dataSource.getConnection();
            conn.setAutoCommit(false);
            transactionHolder.set(conn);
        }
        catch (SQLException e)
        {
            log.error("beginTransaction:从" + DBConst.DEFAULT_CONNECTION_POOL + "数据库连接池获取连接出错", e);
        }
    }
    /**
     * 从当前线程中关闭事务
     */
    public static void commitTransaction()
    {
        Connection conn = (Connection)transactionHolder.get();
        if (conn != null)
        {
            try
            {
                conn.commit();
            }
            catch (SQLException e)
            {
                log.error("commit出错", e);
            }
            finally
            {
                try
                {
                    conn.close();
                }
                catch (SQLException e)
                {
                    log.error("close出错", e);
                }
                transactionHolder.remove();
            }
        }
    }
    
    /**
     * 对于查询方法,复用同一个Connection去查询,和releaseConnection成对使用
     * 
     * @param connectionPoolKey
     * @return
     * @throws SQLException
     */
    public static void openQueryConnection(String connectionPoolKey)
        throws SQLException
    {
        if (!dataSourceMap.containsKey(connectionPoolKey))
        {
            init(connectionPoolKey);
        }
        DataSource dataSource = dataSourceMap.get(connectionPoolKey);
        try
        {
            Connection conn = dataSource.getConnection();
            transactionHolder.set(conn);
        }
        catch (SQLException e)
        {
            log.error("beginQueryConnection:从" + connectionPoolKey + "数据库连接池获取连接出错", e);
        }
        
    }
    /**
     * 从当前线程中 开启查询事务，保存在多个查询中使用的是同一个事务 
     * @param connectionPoolKey
     * @throws SQLException
     */
    public static void openQueryConnection()
            throws SQLException
        {
            if (!dataSourceMap.containsKey(DBConst.DEFAULT_CONNECTION_POOL))
            {
                init(DBConst.DEFAULT_CONNECTION_POOL);
            }
            DataSource dataSource = dataSourceMap.get(DBConst.DEFAULT_CONNECTION_POOL);
            try
            {
                Connection conn = dataSource.getConnection();
                transactionHolder.set(conn);
            }
            catch (SQLException e)
            {
                log.error("beginQueryConnection:从" + DBConst.DEFAULT_CONNECTION_POOL + "数据库连接池获取连接出错", e);
            }
            
        }
    
    /**
     * 对于查询方法,使用完以后,一定要调用此方法释放掉同一个Connection的连接,和getQueryConnection成对使用
     */
    public static void closeQueryConnection()
    {
        Connection conn = (Connection)transactionHolder.get();
        if (conn != null)
        {
            try
            {
            	 if (!conn.isClosed() )
                    conn.close();
            }
            catch (SQLException e)
            {
                log.error("close出错", e);
            }
            transactionHolder.remove();
        }
    }
    
    public static void rollbackTransaction()
    {
        Connection conn = (Connection)transactionHolder.get();
        if (conn != null)
        {
            try
            {
                conn.rollback();
            }
            catch (SQLException e)
            {
                log.error("rollback出错", e);
            }
            finally
            {
                try
                {
                	 if (!conn.isClosed() )
                         conn.close();
                }
                catch (SQLException e)
                {
                    
                    log.error("close出错", e);
                }
                transactionHolder.remove();
            }
        }
    }
    
    private static void init(String connectionPoolKey) {
		 log.error("new initDataSource");
		 // 利用SpringUtil.getBean，注入一个新的DataSource ,先预留 
		
   	}
    
}
